package com.hba;

import com.hba.consumer.MessageBody;
import com.hba.producer.MessageProducer;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class SendTest {

    public static void main(String[] args) throws Exception{
        /*ApplicationContext context = new AnnotationConfigApplicationContext(RabbitConfig.class);
        ConnectionFactory connectionFactory = context.getBean(ConnectionFactory.class);
        RabbitAdmin admin = new RabbitAdmin(connectionFactory);
        admin.declareQueue(new Queue("springQueue"));

        AmqpTemplate amqpTemplate = new RabbitTemplate(connectionFactory);
        amqpTemplate.convertAndSend("springQueue","fsdfs");

        String foo =(String)amqpTemplate.receiveAndConvert("springQueue");
        System.out.println(foo);*/

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring-context.xml");
        MessageProducer messageProducer = applicationContext.getBean(MessageProducer.class);
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                Runtime.getRuntime().availableProcessors() + 1,
                Runtime.getRuntime().availableProcessors() + 20,
                130,
                TimeUnit.MINUTES,
                new ArrayBlockingQueue<Runnable>(50000000),
                new IszThreadFactory(),
                new IszrejectedExecutionHandler()
        );

        for(int i = 0; i<20; i++){
            ThreadTest threadTest = new ThreadTest(messageProducer);
            for(int m = 0; m<100000; m++){
                pool.execute(threadTest);
            }
        }
    }


    private static class IszrejectedExecutionHandler implements RejectedExecutionHandler {
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            throw new RejectedExecutionException("ISZ Task " + r.toString() + " rejected from " + executor.toString());
        }
    }

    public static class IszThreadFactory implements ThreadFactory {
        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        IszThreadFactory() {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
            namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-";
        }

        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r,namePrefix + threadNumber.getAndIncrement(),0);
            if (t.isDaemon())
                t.setDaemon(false);
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }
    }

    static class ThreadTest implements Runnable{
        MessageProducer messageProducer;

        public ThreadTest(MessageProducer messageProducer) {
            this.messageProducer = messageProducer;
        }

        public MessageProducer getMessageProducer() {
            return messageProducer;
        }

        public void setMessageProducer(MessageProducer messageProducer) {
            this.messageProducer = messageProducer;
        }

        public void run() {
            try {
                messageProducer.sendMessage("com.is","--------------------------fdfd--------------------------");
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("errordd:"+e);
            }
        }
    }
}
